package com.huc.netty.handler;

import com.huc.netty.constants.ReqType;
import com.huc.netty.core.Header;
import com.huc.netty.core.RpcProtocol;
import com.huc.netty.core.RpcRequest;
import com.huc.netty.core.RpcResponse;
import com.huc.netty.util.SpringBeanManager;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Method;

/**
 * @author huc
 * @version 1.0
 * @note
 * @date 2021/9/16 10:44
 */
@Slf4j
public class RpcServerHandler extends SimpleChannelInboundHandler<RpcProtocol<RpcRequest>> {
    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, RpcProtocol<RpcRequest> rpcRequestRpcProtocol) throws Exception {
        RpcProtocol<RpcResponse> resProtocol = new RpcProtocol();
        Header header = rpcRequestRpcProtocol.getHeader();
        header.setReqType(ReqType.RESPONSE.code());
        Object result = invoke(rpcRequestRpcProtocol.getContent());
        resProtocol.setHeader(header);
        RpcResponse response = new RpcResponse();
        response.setData(result);
        response.setMsg("success");
        resProtocol.setContent(response);
        channelHandlerContext.writeAndFlush(resProtocol);
    }

    private Object invoke(RpcRequest rpcRequest) {
        try {
            Class<?> clazz = Class.forName(rpcRequest.getClassName());
            Object bean = SpringBeanManager.getBean(clazz);
            Method method = clazz.getDeclaredMethod(rpcRequest.getMethodName(), rpcRequest.getParameterTypes());
            return method.invoke(bean, rpcRequest.getParams());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}
